package com.next.aap.server.persistance.helper;

import java.util.List;

import org.springframework.stereotype.Component;

import com.next.aap.server.persistance.Candidate;
import com.next.core.db.page.PageInfo;
import com.next.core.db.page.PageResult;
import com.next.core.db.page.QueryParam;
import com.next.core.db.validator.ObjectValidator;
import com.next.core.exception.AppException;
import com.next.ext.core.db.page.HibernateQueryParamPageInfo;
import com.next.ext.core.db.page.HibernateQueryParamPageInfo.ORDER;
import com.next.ext.core.persistance.dao.BasePersistanceDao;

@Component
public class CandidateHelper extends BasePersistanceDao<Candidate> implements ObjectValidator<Candidate> {

	/**
	 * Creates/updates a candidate in Database
	 * 
	 * @param candidate
	 * @return saved candidate
	 * @throws AppException
	 */
	public Candidate saveCandidate(Candidate candidate) throws AppException
	{
		checkIfCandidateExistsWithSameName(candidate);
		candidate = super.saveObject(candidate);
		return candidate;
	}

	/**
	 * deletes a candidate in Database
	 * 
	 * @param candidate
	 * @return updated candidate
	 * @throws AppException
	 */
	public void deleteCandidate(Candidate candidate) throws AppException {
		super.deleteObject(candidate);
	}

	/**
	 * return a Candidate with given primary key/id
	 * 
	 * @param id
	 * @return Candidate with PK as id(parameter)
	 * @throws AppException
	 */
	public Candidate getCandidateById(Long id) throws AppException
	{
		Candidate candidate = super.getObjectByPK(Candidate.class, id);
		return candidate;
	}

	/**
	 * @param pageInfo
	 * @return search result
	 * @throws AppException
	 */
	public PageResult<Candidate> searchCandidates(PageInfo pageInfo) throws AppException
	{
		return super.findObject(Candidate.class, pageInfo);
	}

	public List<Candidate> getAllCandidates() throws AppException
	{
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		pageInfo.addOrderBy("name", ORDER.ASC);
		return super.findObject(Candidate.class, pageInfo).getResultList();
	}
	public List<Candidate> getCandidateOfAssemblyConstituency(long assemblyConstituencyId) throws AppException{
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam stateQueryParam = new QueryParam();
		stateQueryParam.setCaseSenstive(false);
		stateQueryParam.setField("assemblyConstituencyId");
		stateQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
		stateQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		stateQueryParam.setValue(assemblyConstituencyId);
		pageInfo.addCriteria(stateQueryParam);
		pageInfo.addOrderBy("name", ORDER.ASC);
		
		PageResult<Candidate> pr = this.searchCandidates(pageInfo);
		List<Candidate> candidateList = pr.getResultList();
		return candidateList;
	}

	public void validateObjectForCreate(Candidate candidate) throws AppException {
		checkIfStringMissing("Name", candidate.getName());
		checkIfObjectMissing("AssemblyConstituency", candidate.getAssemblyConstituency());
	}

	public void validateObjectForUpdate(Candidate candidate) throws AppException {
		checkIfStringMissing("Name", candidate.getName());
		checkIfObjectMissing("AssemblyConstituency", candidate.getAssemblyConstituency());
	}
	private void checkIfCandidateExistsWithSameName(Candidate candidate) throws AppException{
		HibernateQueryParamPageInfo pageInfo = new HibernateQueryParamPageInfo();
		QueryParam emailQueryParam = new QueryParam();
		emailQueryParam.setCaseSenstive(false);
		emailQueryParam.setField("name");
		emailQueryParam.setFieldType(QueryParam.FIELD_TYPE_STRING);
		emailQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		emailQueryParam.setValue(candidate.getName().toUpperCase());
		pageInfo.addCriteria(emailQueryParam);
		
		QueryParam stateQueryParam = new QueryParam();
		stateQueryParam.setField("assemblyConstituencyId");
		stateQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
		stateQueryParam.setOperator(QueryParam.OPERATOR_EQUAL);
		stateQueryParam.setValue(candidate.getAssemblyConstituency().getId());
		pageInfo.addCriteria(stateQueryParam);
		
		if(candidate.getId() != null && candidate.getId() > 0){
			QueryParam candidateIdQueryParam = new QueryParam();
			candidateIdQueryParam.setCaseSenstive(false);
			candidateIdQueryParam.setField("id");
			candidateIdQueryParam.setFieldType(QueryParam.FIELD_TYPE_NUMBER);
			candidateIdQueryParam.setOperator(QueryParam.OPERATOR_NOT_EQUAL);
			candidateIdQueryParam.setValue(candidate.getId());
			pageInfo.addCriteria(candidateIdQueryParam);
		}
		
		PageResult<Candidate> pr = this.searchCandidates(pageInfo);
		if(pr.getResultList().size() > 0){
			throw new AppException("Candidate already exists with name = "+candidate.getName()+" in Assembly Constituency "+candidate.getAssemblyConstituency().getName());
		}
	}
}